package pers.ree.demo.datastructure;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ArrayListDemo {
    static String staticStr = "staticStr"; // 给StaticDemo使用

    public static String staticPublicStr = "staticPublicStr"; // 给StaticDemo使用


    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList();
        arr.add(1);
        arr.add(null);
        arr.add(null);
        arr.add(1);
        System.out.println(arr.size());
        arr.remove(null);
        System.out.println(arr.size());
        arr.remove(1);
        System.out.println(arr.size());

//        int size = 0;
//        Integer[] intArr = new Integer[10];
//        intArr[0]  = 0;
//        intArr[1]  = 1;
//        intArr[size++] = 2;
//        System.out.println(size);

//        int size = 0;
//        Integer[] intArr = new Integer[10];
//        intArr[size++] = 2;
//        System.out.println(size);

    }

    /**
     * @throws InterruptedException
     * list生成迭代器后（expectedModCount已经赋值），
     * 通过另外一个线程修改list的modCount（add操作），
     * 然后在迭代循环中调用迭代器的next或remove方法，
     * 方法中modCount != expectedModCount，抛出ConcurrentModificationException异常
     */
    @Test
    public void modCountDemo() throws InterruptedException {
//        List<Integer> list = new ArrayList<>();
        // 为了方便打印modCount
        SubArrayList<Integer> list = new SubArrayList();

        for (int i=0; i<10; i++) {
            list.add(i);
        }

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                list.add(100);
            }
        });

        System.out.println("before thread1 start, modCount=" + list.getModCount());

        Iterator iterator = list.iterator();

        thread1.start();

        Thread.sleep(10L);

        // 如果把生成iterator的操作放在这里，while循环不会抛出ConcurrentModificationException，
        // 因为expectedModCount已经是thread1修改后的值
//        Iterator iterator = list.iterator();

        System.out.println("after thread1 start, modCount=" + list.getModCount());

        while (iterator.hasNext()) {
            // next或remove中的checkForComodification方法，会判断modCount是否等于expectedModCount，
            // 不相等，则抛出ConcurrentModificationException
            iterator.next();
            iterator.remove();
        }

        System.out.println(list.size());
    }

    /**
     * 使用迭代器在循环中删除元素
     */
    @Test
    public void removeByIterator() {
        List<Integer> list = new ArrayList<>();

        for (int i=0; i<10; i++) {
            list.add(i);
        }

        System.out.println(list);

        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            // 直接执行remove会报错，需要先执行next
//            iterator.remove();

            Integer element = iterator.next();
            if (element % 2 != 0) {
                iterator.remove();
            }
        }

        System.out.println(list);
    }

    /**
     * 倒序循环删除
     */
    @Test
    public void removeByDescOrder() {
        List<Integer> list = new ArrayList<>();

        for (int i=0; i<10; i++) {
            list.add(i);
        }

        for (int i=list.size()-1; i>=0; i--) {
            Integer element = list.get(i);
            if (element % 2 != 0) {
                list.remove(i);
            }
        }

        System.out.println(list);
    }

    /**
     * 正序循环删除元素
     */
    @Test
    public void removeByOrder() {
        List<Integer> list = new ArrayList<>();

        for (int i=0; i<10; i++) {
            list.add(i);
        }

        for (int i=0; i<list.size(); i++) {
//        for (int i=0,size=list.size(); i<size; i++) { // 这种写法则会出现问题，如IndexOutOfBoundsException
            Integer element = list.get(i);
            if (element % 2 != 0) {
                list.remove(i);
                i -= 1; // 关键点
            }
        }

        System.out.println(list);
    }

    static class SubArrayList<E> extends ArrayList<E> {

        public int getModCount() {
            return modCount;
        }
    }
}
